package com.seewo.dubbo.debugger.admin.common;

import com.alibaba.dubbo.common.URL;
import lombok.extern.slf4j.Slf4j;
import org.I0Itec.zkclient.ZkClient;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author chenliangliang
 * @date 2018/7/27
 */
@Slf4j
public class ZookeeperRegistry extends AbstractServiceDiscovery<ZkClient> {


    private volatile ZkClient zkClient;
    private volatile List<List<URL>> serviceProviders;

    public ZookeeperRegistry(String zkAddress, int connectionTimeout) {
        super(zkAddress, connectionTimeout);
    }

    @Override
    protected ZkClient getClient() {
        if (zkClient == null) {
            synchronized (ZookeeperRegistry.class) {
                if (zkClient == null) {
                    zkClient = new ZkClient(address, connectionTimeout);
                    zkClient.subscribeChildChanges(Constants.DUBBO_PREFIX, (parentPath, currentChilds) -> serviceProviders = getEnableServiceProviders0());
                }
            }
        }
        return zkClient;
    }


    public ZookeeperRegistry(String zkAddress) {
        super(zkAddress);
    }


    private List<String> getDubboServices() {
        ZkClient zkClient = getClient();
        return zkClient.getChildren(Constants.DUBBO_PREFIX);
    }

    @Override
    public List<URL> getServiceProvider(String service) {
        if (StringUtils.isEmpty(service)) {
            return Collections.emptyList();
        }

        ZkClient zkClient = getClient();
        final String path = Constants.DUBBO_PREFIX + "/" + service + Constants.DUBBO_PROVIDERS;
        List<String> list = zkClient.getChildren(path);
        List<URL> urls = new ArrayList<>();
        for (String urlStr : list) {
            URL url = URL.valueOf(URL.decode(urlStr));
            urls.add(url);
        }
        return urls;
    }


    @Override
    public List<List<URL>> getEnableServiceProviders() {
        if (serviceProviders == null) {
            synchronized (ZookeeperRegistry.class) {
                if (serviceProviders == null) {
                    serviceProviders = getEnableServiceProviders0();
                }
            }
        }
        return serviceProviders;
    }

    private List<List<URL>> getEnableServiceProviders0() {
        List<String> services = getDubboServices();
        List<List<URL>> res = new ArrayList<>(services.size());
        for (String service : services) {
            List<URL> serviceProvider = getServiceProvider(service);
            if (!serviceProvider.isEmpty()) {
                res.add(serviceProvider);
            }
        }
        log.info("get service providers list: " + res.toString());
        return res;
    }

}
